package com.ktgj.flight.common.pay;

import com.alibaba.fastjson.JSON;
import com.ktgj.common.core.enums.EnumHelper;
import com.ktgj.common.core.utils.DateUtils;
import com.ktgj.common.core.utils.*;
import com.ktgj.common.core.utils.ServletUtils;
import com.ktgj.common.core.utils.StringUtils;
import com.ktgj.flight.common.pay.util.AEScrypt;
import com.ktgj.flight.common.pay.util.CallbackUtil;
import com.ktgj.flight.common.pay.util.DigestUtil;
import com.ktgj.flight.domain.FlightAiraccount;
import com.ktgj.flight.domain.InterfaceEntity.*;
import com.ktgj.flight.service.IFlightAiraccountService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class _Yeepay {

    @Autowired
    private IFlightAiraccountService flightAiraccountService;

    public static String encodingName = "GB2312";

    ///// <summary>
    ///// 瑞丽易宝收款商户
    ///// </summary>
    //private readonly String drYeePayMerId = "10014242594";

    ///// <summary>
    ///// 金色世纪易宝账户登录名
    ///// </summary>
    //private readonly String jsjYeePayLoginName = "menghuili@jsj.com.cn";

    /// <summary>
    /// 第三方渠道易宝收款商户
    /// 10015572302
    /// </summary>
    private String drYeePayMerId = "10015572302";

    /// <summary>
    /// 金色世纪易宝账户登录名
    /// menghuili@jsj.com.cn
    /// </summary>
    private String jsjYeePayLoginName = "menghuili@jsj.com.cn";

    /// <summary>
    /// 易宝支付异步通知收款方测试环境地址
    /// </summary>
//    private String serverNotifyUrl = "https://test.ileiming.com/pay-88/pay/yeepay/notify";

    /**
     * 易宝支付异步通知收款方正式环境地址
     */
    private String serverNotifyUrl = "http://stone.chinaexpressair.com:8135/pay/yeepay/notify";

    /// <summary>
    /// 金色世纪易宝支付商户密钥
    /// （menghuili@jsj.com.cn--06xuL6Ls1T298G7vW3L71jK1480r6sT3T16T85uCz9Ah8XkQjRCNaN11462W）
    /// （wanhua@jsj.com.cn--784PuLj2d54f08C7R9k1B2L31a88cx6817zP8DbQYfzyS2zLpYh4n742R4n3）
    /// </summary>
    private String jsjSecretkey = "06xuL6Ls1T298G7vW3L71jK1480r6sT3T16T85uCz9Ah8XkQjRCNaN11462W";

    /// <summary>
    /// 支付回调地址:gc.jsjinfo.cn（本地外网回调地址：106.38.39.175）
    /// </summary>
    private String urlCallback = "http://106.38.39.137:8080/flight/callback/yeepayTicketCallback";

    /// <summary>
    /// 支付请求地址
    /// </summary>
    private String strPayUrl = "https://www.yeepay.com/app-airsupport/AirSupportCommand.action?";


    //秘钥
    private String PayKey = "ECC3B84516FB432898FC072D4A1E4B7F";
    private String PayName = "wanhua@jsj.com.cn";
    private String PayPwd = "zbjj23070104";
    private String PartnerID = "YP10013368136";
    private String Tel = "";
    private String Contranctor = "";
    private String Url = "https://airt.yeepay.com/air-ticket-api/airb2b/command.action";


//    易宝生产环境相关节点：
//    <YeeBao>
//      <!--Api地址-->
//      <Url>https://airt.yeepay.com/air-ticket-api/airb2b/command.action</Url>
//      <!--商户标识（商户号：10013368136）-->
//      <PartnerID>YP10013368136</PartnerID>
//      <!--密钥 正式：2392B59F09EB4D26873403895DAF7739-->
//      <PayKey>ECC3B84516FB432898FC072D4A1E4B7F</PayKey>
//      <!--支付账号-->
//      <PayName>wanhua@jsj.com.cn</PayName>
//      <!--支付密码yxh23070104-->
//      <PayPwd>zbjj23070104</PayPwd>
//
//      <Contranctor></Contranctor>
//      <!--联系手机号-->
//      <Tel></Tel>
//      <!--联系邮箱-->
//      <Email></Email>
//      <!--地址-->
//      <Addr>北京市朝阳区来广营西路5号森根国际2E座</Addr>
//
//    </YeeBao>

    //region 易宝商旅自动出票配置
    //易宝商旅自动出票地址
    private String ticketUrl = "https://airt.yeepay.com/air-ticket-api/airb2b/command.action";
    //易宝商旅出票秘钥
    private String ticketPayKey = "ECC3B84516FB432898FC072D4A1E4B7F";
    //易宝商旅出票账户
    private String ticketPayName = "wanhua@jsj.com.cn";
    //易宝商旅出票支付密码
    private String ticketPayPwd = "zbjj23070104";
    //易宝商旅出票商户号
    private String ticketPartnerID = "YP10013368136";
    //endregion

    public _Yeepay() {

    }

    /**
     * @param drYeePayMerId      第三方出票渠道易宝收款商户
     * @param jsjYeePayLoginName 金色世纪对应第三方渠道易宝支账户登录名
     * @param jsjSecretkey       金色世纪易宝支付商户密钥
     * @param serverNotifyUrl    收款方回调地址
     */
    public _Yeepay(String drYeePayMerId, String jsjYeePayLoginName, String jsjSecretkey, String serverNotifyUrl) {
        this.drYeePayMerId = drYeePayMerId;
        this.jsjYeePayLoginName = jsjYeePayLoginName;
        this.jsjSecretkey = jsjSecretkey;
        this.serverNotifyUrl = serverNotifyUrl;
    }

    /**
     * 易宝OTA航司旗舰店支付
     * @param moRequest
     * @return
     */
    public MoOrderPayResponse _OrderPayment(MoYeePayRequest moRequest) {
        moRequest.OnlyCode = moRequest.OnlyCode != null ? moRequest.OnlyCode : strOnlyCode();
        MoOrderPayResponse response = new MoOrderPayResponse();
        response.OnlyCode = moRequest.OnlyCode;
        response.ProviderCode = moRequest.ProviderCode;
        response.RequestType = moRequest.RequestType;
        String strRequestData = "";
        String strResponseData = "";
        Date requestTime = new Date();
        Date returnTime = new Date();
//        boolean IsCanPay = false;
//        if (IsCanPay == true) {
//            urlCallback = "http://gc.jsjinfo.cn/BSCRM/Ticket/AutoIssue/Callback/YeepayPaymentCallback.aspx";
//        } else {
//            urlCallback = "http://106.38.39.175/BSCRM/Ticket/AutoIssue/Callback/YeepayPaymentCallback.aspx";
//        }
        try {
            //验证
            //ExternalNo注解：瑞丽为支付订单号，华夏为订单编码
            if (StringUtils.isEmpty(moRequest.ExternalNo)) {
                response.ErrorMsg = "第三方支付订单号-不能为空";
                response.IsSuccess = false;
                return response;
            }
            if (moRequest.RequestType == EnumHelper.RequestType.G5 && StringUtils.isEmpty(moRequest.OrderID)) {
                response.ErrorMsg = "商户订单号-不能为空";
                response.IsSuccess = false;
                return response;
            }
            if (StringUtils.isEmpty(moRequest.PayAmount.toString())) {
                response.ErrorMsg = "支付金额-不能为空";
                response.IsSuccess = false;
                return response;
            }
            String p0_Cmd = "PayerBuyDirect";
            String p1_MerId = drYeePayMerId;
            String p1_RequestId = moRequest.RequestType == EnumHelper.RequestType.G5 ? moRequest.OrderID : moRequest.ExternalNo;
            String p3_Amt = moRequest.PayAmount.toString();
            String p4_Cur = "CNY";
            String p5_Pid = moRequest.OrderID;//moRequest.RequestType == EnumHelper.RequestType.华夏 ? moRequest.ExternalNo : "";//华夏约定传订单号
            String p5_Pdetail = moRequest.OrderID;
            String p6_CallbackUrl = "";
            String p6_NotifyUrl = urlCallback;
            String p7_MP = "";
            String pf_LoginName = jsjYeePayLoginName;
            String pb_ServerNotifyUrl = serverNotifyUrl;
            //String pr_NeedResponse = "1";
            //String pd_Pcat = "";
            StringBuilder strhm = new StringBuilder();
            strhm.append(p0_Cmd);
            strhm.append(p1_MerId);
            strhm.append(p1_RequestId);
            strhm.append(p3_Amt);
            strhm.append(p4_Cur);
            strhm.append(p5_Pid);
            strhm.append(p5_Pdetail);
            strhm.append(p6_CallbackUrl);
            strhm.append(p6_NotifyUrl);
            strhm.append(p7_MP);
            strhm.append(pf_LoginName);
            strhm.append(pb_ServerNotifyUrl);
            //strhm.append(pr_NeedResponse);
            //strhm.append(pd_Pcat);

            String tempStr = HmacSign(strhm.toString(), jsjSecretkey);
            StringBuilder strSarms = new StringBuilder();
            strRequestData = strSarms.toString();

            strSarms.append(String.format("p0_Cmd=%s", p0_Cmd));
            strSarms.append(String.format("&p1_MerId=%s", p1_MerId));
            strSarms.append(String.format("&p1_RequestId=%s", p1_RequestId));
            strSarms.append(String.format("&p3_Amt=%s", p3_Amt));
            strSarms.append(String.format("&p4_Cur=%s", p4_Cur));
            strSarms.append(String.format("&p5_Pid=%s", p5_Pid));
            strSarms.append(String.format("&p5_Pdetail=%s", p5_Pdetail));
            strSarms.append(String.format("&p6_CallbackUrl=%s", p6_CallbackUrl));
            strSarms.append(String.format("&p6_NotifyUrl=%s", p6_NotifyUrl));
            strSarms.append(String.format("&p7_MP=%s", p7_MP));
            strSarms.append(String.format("&pf_LoginName=%s", pf_LoginName));
            strSarms.append(String.format("&pb_ServerNotifyUrl=%s", pb_ServerNotifyUrl));
            //strSarms.append(String.format("&pr_NeedResponse=%s", pr_NeedResponse));
            //strSarms.append(String.format("&pd_Pcat=%s", pd_Pcat));
            strSarms.append(String.format("&hmac=%s", tempStr));
            //strResponseData = SendRequest(strPayUrl, strSarms.toString(), "GET");
            Map<String, String> result = httpRequest(strPayUrl, strSarms.toString(), "GET", encodingName);
            String code = result.put("r1_Code", result.get("r1_Code"));
            if (code.equals("1")) {
                String requestId = result.put("r1_RequestId", result.get("r1_RequestId")); //商户订单号
                String trxId = result.put("r2_TrxId", result.get("r2_TrxId")); //易宝支付交易流水号
                String amt = result.put("r3_Amt", result.get("r3_Amt")); //支付金额（单位：元，精确到分）
                String pid = result.put("r5_Pid", result.get("r5_Pid")); //商品名称 易宝支付返回商户设置的商品名称
                response.PayInfo.PayAmount = new BigDecimal(amt);
                response.PayInfo.SwiftNumber = trxId;
                response.IsSuccess = true;
                response.ErrorMsg = "交易成功";
            } else {
                String errorMsg = result.put("errorMsg", result.get("errorMsg")); //r1_Code不等于1时为错误信息
                response.IsSuccess = false;
                response.ErrorMsg = errorMsg;
                return response;
            }

//            String r0_Cmd = FormatQueryString.GetQueryString("r0_Cmd", strResponseData, '\n');
//            String r1_Code = FormatQueryString.GetQueryString("r1_Code", strResponseData, '\n');
//            String r2_TrxId = FormatQueryString.GetQueryString("r2_TrxId", strResponseData, '\n');
//            String r6_Order = FormatQueryString.GetQueryString("r6_Order", strResponseData, '\n');
//            String errorMsg = FormatQueryString.GetQueryString("errorMsg", strResponseData, '\n');
//            String nhmac = FormatQueryString.GetQueryString("hmac", strResponseData, '\n' );
            returnTime = new Date();
//            if (StringUtils.isWhitespace(strResponseData)) {
//                response.ErrorCode = EnumHelper.ReturnCode.ReturnCode10006.toString();
//                response.ErrorMsg = "支付失败，未返回数据";
//                response.IsSuccess = false;
//                return response;
//            } else if ("PayerBuyDirect".equals(r0_Cmd) && "1".equals(r1_Code)) {
//                response.ErrorCode = EnumHelper.ReturnCode.ReturnCode1000.toString();
//                response.ErrorMsg = "支付成功";
//                response.IsSuccess = true;
//            } else if (!"1".equals(r1_Code)) {
//                response.ErrorCode = EnumHelper.ReturnCode.ReturnCode10020.toString();
//                response.ErrorMsg = errorMsg;
//                response.IsSuccess = false;
//                return response;
//            }
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
            return response;
        } finally {

        }
        return response;
    }


    /**
     * 查询PNR政策
     *
     * @param request
     * @return
     */
    public MoAutoPayOutTickeResponse _GetPolicyByPnr(MoAutoPayOutTicketRequest request) {
        String strRequest = "";
        String strResult = "";
        Date ReturnTime = DateUtils.getNowDate();
        MoAutoPayOutTickeResponse response = new MoAutoPayOutTickeResponse();
        response.RequestType = request.RequestType;
        String url = ticketUrl;
        if (Strings.isEmpty(request.OrderID)) {
            response.ErrorCode = String.valueOf(EnumHelper.ReturnCode.请求参数为空.getValue());
            response.ErrorMsg = "金色订单号不能为空";
            return response;
        }
        if (Strings.isEmpty(request.BigPnr)) {

            response.ErrorCode = String.valueOf(EnumHelper.ReturnCode.请求参数为空.getValue());
            response.ErrorMsg = "大Pnr编号不能为空";
            return response;
        }
        if (Strings.isEmpty(request.AirCode)) {
            response.ErrorCode = String.valueOf(EnumHelper.ReturnCode.请求参数为空.getValue());
            response.ErrorMsg = "航司二字码不能为空";
            return response;
        }

        String airUser = request.AirUser;
        //todo 从数据库中获取B2B航司用户名和密码
        FlightAiraccount flightAiraccount = flightAiraccountService.selectFlightAirAccountByAirlinerId(request.AirCode);
        if (flightAiraccount != null) {
            airUser = String.format("username=%s&pwd=%s", flightAiraccount.getLoginid(), flightAiraccount.getPassword());
        }

        String airCodeKey = request.AirCode.toUpperCase();
        if (airCodeKey.equals("HU") || airCodeKey.equals("CZ")) {
            request.AirCode = "AIR_" + airCodeKey + "_NEW";
        } else if (airCodeKey.equals("MU") || airCodeKey.equals("FM")) {
            request.AirCode = "AIR_" + airCodeKey + "_B2T";
        } else {
            request.AirCode = "AIR_" + airCodeKey;
        }


        /*
        if (String.IsNullOrEmpty(airUser))
        {
            //如果航司账号密码为空，使用api中默认账号密码
            var airUserInfo = AirCodeLoginConfig._CurrentAirLogins().Where(b => b.AirCode == airCodeKey).SingleOrDefault();
            if (airUserInfo == null)
            {

                response.ErrorCode = ((int)EnumHelper.ReturnCode.失败).ToString();
                response.ErrorMsg = "未能找到指定航司登陆信息";
                return response;
            }

            airUser = String.Format("username={0}&pwd={1}", airUserInfo.UserName, airUserInfo.UserPwd);
        }*/

        //秘钥
        String key = ticketPayKey;
        //航司账号：格式:a=xx&b=xxx再使用aes加密
        airUser = AEScrypt.encryptAES(airUser, key);
//        airUser = AesUtil.encrypt(airUser, key);
        //签名字段：cmd,customersign,requestid,aircode,b2buser,pnr,bigcid
        String partnerId = ticketPartnerID;
        String sign = String.format("GetPrice" +
                partnerId +
                request.OrderID +
                request.AirCode +
                airUser +
                request.BigPnr);
        try {
            sign = DigestUtil.hmacSign(sign, key);
        } catch (Exception ex) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = ex.getMessage() + ex.getStackTrace();
        }
        StringBuilder sbParam = new StringBuilder();
        sbParam.append(String.format("cmd=%s&", "GetPrice"));
        sbParam.append(String.format("customersign=%s&", partnerId));   //b2b商户编号
        sbParam.append(String.format("requestid=%s&", request.OrderID));   //
        sbParam.append(String.format("aircode=%s&", request.AirCode));  //航司二字码
        sbParam.append(String.format("b2buser=%s&", airUser));     //航司账号
        sbParam.append(String.format("pnr=%s&", request.BigPnr));   //航司大编
        sbParam.append(String.format("hmac=%s", sign));   //签名
        strRequest = sbParam.toString(); //HttpUtility.UrlEncode(sbParam.ToString());
        strResult = HttpClientUtil._PostUrlHtml(url, strRequest.getBytes(), "application/x-www-form-urlencoded", false, "");
        strResult = ServletUtils.urlDecode(strResult);
        PolicyByPnr res = JSON.parseObject(strResult, PolicyByPnr.class);
        if (res.priceList == null || res.priceList.size() <= 0) {
            response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
            response.ErrorMsg = res.executeMsg;
            response.IsSuccess = false;
            return response;
        }
        List<MoAutoPayOutTickeResponse> policies = new ArrayList<>();
        for (PriceList item : res.priceList) {
            MoAutoPayOutTickeResponse policy = new MoAutoPayOutTickeResponse();
            policy.PayAmount = BigDecimal.valueOf(item.payPrice);
            policy.Tax = BigDecimal.valueOf(item.tax);
            policy.TicketAmount = BigDecimal.valueOf(item.ticketPar);
            policy.MoPolicy.Ply_CommisionRate = BigDecimal.valueOf(item.rebates);
            policies.add(policy);
        }

        if (policies.size() > 0) {
            MoAutoPayOutTickeResponse policy = policies.stream().findFirst().orElse(null);
            if (policy != null) {
                response.PayAmount = policy.PayAmount;
                response.Tax = policy.Tax;
                response.TicketAmount = policy.TicketAmount;
                response.MoPolicy.Ply_CommisionRate = policy.MoPolicy.Ply_CommisionRate;
                response.IsSuccess = true;
            }
        }
        return response;
    }

    /**
     * 自动出票前数据校验
     * @param request
     * @return
     */
    public OutTicketCheckResponse checkOutTicket(MoAutoPayOutTicketRequest request) {
        OutTicketCheckResponse response=new OutTicketCheckResponse();
        try {
            MoAutoPayOutTicketRequest requestPolicy = new MoAutoPayOutTicketRequest();
            requestPolicy.BigPnr = request.BigPnr;
            requestPolicy.AirCode = request.AirCode;
            requestPolicy.AirUser = request.AirUser;//"username=PEK602&pwd=pek883266";
            requestPolicy.OrderID = request.OrderID;
            requestPolicy.RequestType = request.RequestType;
            requestPolicy.OnlyCode = request.OnlyCode;
            MoAutoPayOutTickeResponse responsePolicy = _GetPolicyByPnr(requestPolicy);
            if (!responsePolicy.IsSuccess) {
                response.setCode(responsePolicy.ErrorCode);
                response.setMsg(responsePolicy.ErrorMsg);
                response.setSuccess(false);
                return response;
            }



            //验证  易宝出票增加票价，税费参数
            if (request.PayAmount.compareTo(responsePolicy.PayAmount) < 1) {
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("待支付总价格高于预定价格");
                response.setSuccess(false);
                return response;
            } else if (request.TicketAmount.doubleValue() > 0) {
                if (request.TicketAmount.add(request.Tax).doubleValue() < responsePolicy.TicketAmount.add(responsePolicy.Tax).doubleValue()) {
                    response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                    response.setMsg("待支付票价高于预定价格");
                    response.setSuccess(false);
                    return response;
                }
            }

            //如果正确，那么进行下单，支付，出票
            request.Tax = responsePolicy.Tax;
            request.TicketAmount = responsePolicy.TicketAmount;
            request.Commision = responsePolicy.MoPolicy.Ply_CommisionRate;
            request.PayAmount = responsePolicy.PayAmount;

            if (Strings.isEmpty(request.OrderID)) {
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("金色订单号不能为空");
                response.setSuccess(false);
                return response;
            }
            if (Strings.isEmpty(request.BigPnr)) {
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("大Pnr编号不能为空");
                response.setSuccess(false);
                return response;
            }
            if (Strings.isEmpty(request.AirCode)) {
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("航司二字码不能为空");
                response.setSuccess(false);
                return response;
            }
            if (request.TicketAmount.doubleValue() <= 0) {
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("总票面价格应大于0");
                response.setSuccess(false);
                return response;
            }
            if (request.Tax.doubleValue() <= 0) {
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("总税费应该大于0");
                response.setSuccess(false);
                return response;
            }
            if (request.PayAmount.doubleValue() <= 0) {
                response.setSuccess(false);
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("支付总金额应该大于0");
                return response;
            }

            if (request.Commision.doubleValue() < 0) {
                response.setSuccess(false);
                response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                response.setMsg("最低返点应该大于0");
                return response;
            }

            String airUser = request.AirUser;
            if (Strings.isEmpty(airUser)) {
                FlightAiraccount flightAiraccount = flightAiraccountService.selectFlightAirAccountByAirlinerId(request.AirCode);

                if (flightAiraccount == null) {
                    response.setSuccess(false);
                    response.setCode(EnumHelper.ReturnCode.失败.toString());
                    response.setMsg("未能找到指定航司登陆信息");
                    return response;
                }
                airUser = String.format("username=%s&pwd=%s", flightAiraccount.getLoginid(), flightAiraccount.getPassword());

            }

            String airCodeKey = request.AirCode.trim().toUpperCase();
            if ("HU".equals(airCodeKey) || "CZ".equals(airCodeKey)) {
                request.AirCode = "AIR_" + airCodeKey + "_NEW";
            } else if ("MU".equals(airCodeKey) || "FM".equals(airCodeKey)) {
                request.AirCode = "AIR_" + airCodeKey + "_B2T";
            } else {
                request.AirCode = "AIR_" + airCodeKey;
            }


            //联系人信息验证
            String tel = Tel;
            if (Strings.isEmpty(tel)) {
                if (Strings.isEmpty(request.MoContacts.ContactMobile)) {
                    response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                    response.setMsg("联系人电话不能为空");
                    response.setSuccess(false);
                    return response;
                } else {
                    tel = request.MoContacts.ContactMobile;
                }
            }

            //联系人
            String contranctor = Contranctor;
            if (Strings.isEmpty(contranctor)) {
                if (Strings.isEmpty(request.MoContacts.ContactName)) {
                    response.setCode(EnumHelper.ReturnCode.请求参数为空.toString());
                    response.setMsg("联系人不能为空");
                    response.setSuccess(false);
                    return response;
                } else {
                    contranctor = request.MoContacts.ContactMobile;
                }
            }


            //构建参数
            String key = PayKey;
            String payUser = String.format("UserName=%s&pwd=%s&frpId=%s", PayName, PayPwd, "M_P");
            payUser = AEScrypt.encryptAES(payUser, key);
            airUser = AEScrypt.encryptAES(airUser, key);

            String partnerId = PartnerID;
            String sign = "AutoPay" + partnerId + request.OrderID + request.AirCode + airUser + payUser + request.BigPnr + request.TicketAmount
                    + request.Tax + request.PayAmount + request.Commision + tel + contranctor;

            sign = DigestUtil.hmacSign(sign, key);


            StringBuilder sbParam = new StringBuilder();

            sbParam.append(String.format("cmd=%s&", "AutoPay"));
            sbParam.append(String.format("customersign=%s&", partnerId)); //b2b商户编号
            sbParam.append(String.format("requestid=%s&", request.OrderID));
            sbParam.append(String.format("aircode=%s&", request.AirCode));  //航司二字码
            sbParam.append(String.format("b2buser=%s&", airUser)); //航司账号
            sbParam.append(String.format("yeepayuser=%s&", payUser)); //支付账号

            sbParam.append(String.format("pnr=%s&", request.BigPnr)); //航司大编
            sbParam.append(String.format("ticketpar=%s&", request.TicketAmount));   //总票面价
            sbParam.append(String.format("tax=%s&", request.Tax));  //总税费
            sbParam.append(String.format("payprice=%s&", request.PayAmount)); //总支付金额
            sbParam.append(String.format("rebates=%s&", request.Commision)); //返点

            sbParam.append(String.format("mobile=%s&", tel)); //联系手机号
            sbParam.append(String.format("linkman=%s&", contranctor)); //联系人
            sbParam.append(String.format("hmac=%s", sign)); //签名

            response.setSource(sbParam.toString());
            response.setSuccess(true);
            response.setOrderId(request.OrderID);
            response.setBigPnr(request.BigPnr);


        } catch (Exception e) {
            response.setCode(EnumHelper.ReturnCode.系统异常代码.toString());
            response.setMsg(e.getMessage());
            response.setSuccess(false);
            return response;
        }

        return response;
    }


    public MoAutoPayOutTickeResponse _AutoPayOutTicket(String strRequest,String OrderID,String BigPnr) {
        String strResult="";
        MoAutoPayOutTickeResponse response = new MoAutoPayOutTickeResponse();
        try {
            //请求
            String url = Url;
            strResult = HttpClientUtil._PostUrlHtml(url, strRequest.getBytes(), "application/x-www-form-urlencoded", false, "");
            strResult = ServletUtils.urlDecode(strResult);

            AutoPayOutTicket res = JSON.parseObject(strResult, AutoPayOutTicket.class);

            if ("ZF0001".equals(res.executeCode)) {
                response.ErrorCode = EnumHelper.ReturnCode.解析返回信息异常.toString();
                response.ErrorMsg = "接口返回:" + res.executeMsg + "请检查是否已出票";
                response.IsSuccess=false;
                return response;
            } else if (!"CP0001".equals(res.executeCode)) {
                response.ErrorCode = EnumHelper.ReturnCode.解析返回信息异常.toString();
                response.ErrorMsg = res.executeMsg;
                response.IsSuccess=false;
                return response;
            }

            String status = res.executeStatus;
            String statusMsg = "";
            if ("TICKET_SUCCESS".equals(status)) {
                statusMsg = EnumHelper.OrderStatus.出票完成.toString();
            } else if ("ORDERPAY_SUCCESS".equals(status)) {
                statusMsg = EnumHelper.OrderStatus.扣款成功.toString();
            } else if ("ORDERPAY_FAIL".equals(status)) {
                statusMsg = EnumHelper.OrderStatus.扣款失败.toString();
            } else if ("TICKET_FAIL".equals(status)) {
                statusMsg = EnumHelper.OrderStatus.出票失败.toString();
            }


            //失败
            if (!"TICKET_SUCCESS".equals(res.executeStatus.trim().toUpperCase()) && !"ORDERPAY_SUCCESS".equals(res.executeStatus.trim().toUpperCase())) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = res.executeStatus + res.executeMsg;

                // todo 如果失败，那么需要调用取消入库操作

            }

            //成功的处理
            if (res.orderInfo == null) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = "解析订单信息-异常;" + res.executeMsg;
                return response;
            }
            if (res.priceList == null || res.priceList.size() <= 0) {
                response.ErrorCode = EnumHelper.ReturnCode.失败.toString();
                response.ErrorMsg = "解析价格信息-异常;" + res.executeMsg;
                return response;
            }

            com.ktgj.flight.domain.InterfaceEntity.PriceList item = res.priceList.get(0);

            //第三方订单号
            response.OrderID = OrderID;
            response.OutOrderID = res.orderInfo.orderId;
            response.Tax = new BigDecimal(item.tax);
            response.TicketAmount = new BigDecimal(item.ticketPar);
            response.PayAmount = new BigDecimal(item.payPrice);
            response.BigPnr = BigPnr;
            response.IsSuccess = Strings.isEmpty(response.ErrorMsg);
            response.statusMsg = statusMsg;
            response.startTicketNo=res.startTicketNo;
            response.guestList = res.guestList;

        } catch (Exception e) {
            response.ErrorCode = EnumHelper.ReturnCode.系统异常代码.toString();
            response.ErrorMsg = e.getMessage();
            return response;
        }

        return response;
    }


    public static Map<String, String> httpRequest(String url, String params, String method, String charSet) throws Exception {
        String result = CallbackUtil.httpRequest(url, params, method, charSet);
        if (StringUtils.isEmpty(result)) {
            throw new Exception("result is null");
        } else {
            Map<String, String> resultMap = CallbackUtil.queryString(result, "\n");
            if (resultMap == null) {
                throw new Exception("resultMap is null");
            } else {
                return resultMap;
            }
        }
    }


    public static String HmacSign(String aValue, String aKey) throws Exception {
        byte k_ipad[] = new byte[64];
        byte k_opad[] = new byte[64];
        byte keyb[];
        byte value[];
        try {
            keyb = aKey.getBytes(encodingName);
            value = aValue.getBytes(encodingName);
        } catch (UnsupportedEncodingException e) {
            keyb = aKey.getBytes();
            value = aValue.getBytes();
        }
        Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
        Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
        for (int i = 0; i < keyb.length; ++i) {
            k_ipad[i] = (byte) (keyb[i] ^ 54);
            k_opad[i] = (byte) (keyb[i] ^ 92);
        }
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
        md.update(k_ipad);
        md.update(value);
        byte dg[] = md.digest();
        md.reset();
        md.update(k_opad);
        md.update(dg, 0, 16);
        dg = md.digest();
        return toHex(dg);
    }

    public static String toHex(byte[] input) {
        if (input == null) {
            return null;
        } else {
            StringBuffer output = new StringBuffer(input.length * 2);

            for (int i = 0; i < input.length; ++i) {
                int current = input[i] & 255;
                if (current < 16) {
                    output.append("0");
                }
                output.append(Integer.toString(current, 16));
            }
            return output.toString();
        }
    }

    public static String getHmac(String[] args, String key) throws Exception {
        if (args != null && args.length != 0) {
            StringBuffer str = new StringBuffer();

            for (int i = 0; i < args.length; ++i) {
                str.append(args[i]);
            }
            return HmacSign(str.toString(), key);
        } else {
            return null;
        }
    }

    public static String digest(String aValue) {
        aValue = aValue.trim();
        byte[] value;
        try {
            value = aValue.getBytes(encodingName);
        } catch (UnsupportedEncodingException var5) {
            value = aValue.getBytes();
        }
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA");
        } catch (NoSuchAlgorithmException var4) {
            var4.printStackTrace();
            return null;
        }
        return toHex(md.digest(value));
    }

    private String data(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(date);
    }

    private String strOnlyCode() {
        return data(new Date()) + new Random().ints(1000, 10000);
    }

    public static class PolicyByPnr implements Serializable {
        public String pnrInfo;
        public String cmd;
        public String executeStatus;
        public String requestId;
        public List<PriceList> priceList;
        public String executeMsg;
        public String customerSign;
        public String executeCode;
        public List<TripList> tripList;
        public String pnrStr;
    }

    public static class PriceList implements Serializable {
        public double fixedFee;
        public double payPrice;
        public double tax;
        public double rebates;
        public double amtAdulPrice;
        public double ticketPar;

    }

    public static class TripList implements Serializable {
        public String airNo;
        public String airDstTime;
        public String dstCity;
        public String airOrgTime;
        public String orgCity;
        public String bunkNo;
    }
}
